﻿using System;
using System.IO;
using System.Collections.Generic;

namespace Network.Messages {
    public abstract class SerializeAble {
        abstract public int Serialize( BinaryWriter s );
        abstract public int Deserialize( BinaryReader s );
    }

    public abstract class BaseMessage : SerializeAble {
        public const int BYTE_BUFFER_SIZE = 40960;
        public const int MAX_STRING_LEN = 4096 * 8;

        abstract public MessageType GetId();
        static public BaseMessage Create( BinaryReader s ) {
            return null;
        }
        public override int Serialize( BinaryWriter s ) {
            throw new NotImplementedException();
        }
        public override int Deserialize( BinaryReader s ) {
            throw new NotImplementedException();
        }
    }

    public partial class MessageFactory {
        public delegate BaseMessage CreateFunc( BinaryReader s );
        public class Item {
            public CreateFunc create;
        }
        static private Dictionary<MessageType, Item> items = new Dictionary<MessageType, Item>();
        static private Dictionary<Type, MessageType> types = new Dictionary<Type, MessageType>();
        static public MessageType GetMessageId<T>() where T : BaseMessage {
            MessageType id;
            if ( types.TryGetValue( typeof( T ), out id ) ) {
                return id;
            } else {
                return MessageType.MSG_Undefined;
            }
        }
        static public MessageType GetMessageId( Type type ) {
            MessageType id;
            if ( types.TryGetValue( type, out id ) ) {
                return id;
            } else {
                return MessageType.MSG_Undefined;
            }
        }
        static public bool RegisterMessageId( MessageType id, CreateFunc func ) {
            if ( items.ContainsKey( id ) ) {
                return false;
            }
            if ( types.ContainsKey( func.Method.DeclaringType ) ) {
                return false;
            }
            Item item = new Item();
            item.create = func;
            items.Add( id, item );
            types.Add( func.Method.DeclaringType, id );
            return true;
        }
        static public BaseMessage Create( MessageType id, BinaryReader s ) {
            Item item;
            if ( items.TryGetValue( id, out item ) ) {
                return item.create( s );
            }
            return null;
        }
    }
}
//EOF
